#ifndef __CLIENT__
#define __CLIENT__

#include <cassert>

#include "Msg\hzCommander.h"
#include "..\Common\CommonWinsock.h"
#include "..\Common\CommonNetwork.h"
#include "..\Common\CommonThread.h"

#include "ClientBase.h"
#include "ClientObjectManager.h"
#include "ClientServiceRequester.h"


const int INVALID_CLIENT_CODE = 0;

class client : public client_base {
private:
	network*		m_ServiceNetwork;
	network*		m_BroadcastNetwork;
	network*		m_UDPNetwork;	
	
	// sub component's ptr.
	service_requester*	m_pServiceRequester;
	object_manager*		m_pObjectManager;
	hz::commander*		m_pCommander;	// chat box window
	thread_manager		m_ThreadManager;
	HWND				m_MainWindowHWND;

	unsigned int		m_ClientCode;
	string				m_ServerIP;
	int					m_ServerUdpPort;

	// for debug order.
	bool	m_MoniterBroadcastMessage;
	float   m_BorderOneFrameTime;   

	bool Ready(network* pServiceNetwork);
	bool RegistMyShip(void);

public:
	client(void);
	~client(void);

	void LinkCommander(hz::commander* pCommander);
	void LinkObjectManager(object_manager* pObjectManager);	
	void LinkServiceRequester(service_requester* pServiceRequester);			
	void SetMainWindowHWND(HWND MainWindowHWND);	
	
	bool Connect(const string& ServerIP, int ServiceListenPort, int BroadcastListenPort, 
				int ServerUdpPort, int ClientUDPPort);	
	void EndClient(void);
	
	void SetClientCode(unsigned int ClientCode);
	unsigned int GetClientCode(void);

	void Error(ERROR_CODE ErrorCode);
	void CriticalError(int ErrorCode);
	void NormalError(int ErrorCode);	
	
	network*		GetUDPNetwork(void)		{ return m_UDPNetwork; }
	string			GetServerIP(void)		{ return m_ServerIP; }
	int				GetServerUdpPort(void)	{ return m_ServerUdpPort; }		
	thread_manager& ThreadManager(void)		{ return m_ThreadManager; }
	void			Focus(void)				{ SetFocus(m_MainWindowHWND); }


	void Commander(void);
	/*void BroadcastReceive(void);*/    // broadcast method. but network's event too slow. so now working to thread

	// for debug order. 
	bool SwitchMoniterBroadcaster(void) { m_MoniterBroadcastMessage = !m_MoniterBroadcastMessage; 
										  return m_MoniterBroadcastMessage; }
	bool GetMoniterBroadcaster(void)	{ return m_MoniterBroadcastMessage; }
	float GetBorderFrameTime(void)		{ return m_BorderOneFrameTime; }
	void SetBorderFrameTime(float Time) { m_BorderOneFrameTime = Time; }	
};

#endif